#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time      :2021/7/16 15:57
# @Author    :cjw
from typing import Optional

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate, UserInDB
from app.core.security import verify_password, get_password_hash
from app.crud.base import CRUDBase


class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):

    def get_by_email(self, db: Session, *, email: str) -> Optional[User]:
        """
        根据邮箱查询用户
        :param db: 数据库连接
        :param email: 邮箱地址
        :return:
        """
        stmt = select(self.model).where(User.email == email)
        return db.execute(stmt).scalar_one_or_none()

    def create(self, db: Session, *, obj_in: UserCreate) -> User:
        """
        创建用户
        :param db: 数据库连接
        :param obj_in: 创建用户对象
        :return:
        """
        db_obj = User(**obj_in.dict(exclude={'password'}), hashed_password=get_password_hash(obj_in.password))
        db.add(db_obj)
        db.commit()
        return db_obj

    def update(self, db: Session, *, db_obj: User, obj_in: UserUpdate) -> User:
        """
        更新用户
        :param db: 数据库连接
        :param db_obj: 数据库模型对象
        :param obj_in: schema模型更新对象
        :return:
        """
        if obj_in.password:
            update_data = obj_in.dict(exclude_unset=True)
            hashed_password = get_password_hash(obj_in.password)
            del update_data['password']
            update_data['hashed_password'] = hashed_password
            use_obj_in = UserInDB.parse_obj(update_data)
        return super(CRUDUser, self).update(db, db_obj=db_obj, obj_in=use_obj_in)

    def authenticate(self, db: Session, *, email: str, password: str):
        """
        用户校验
        :param db: 数据库连接
        :param email: 邮箱
        :param password: 密码
        :return:
        """
        user = self.get_by_email(db, email=email)
        if not user:
            return None
        if not verify_password(password, user.hashed_password):
            return None
        return user

    def is_active(self, current_user: User) -> bool:
        """
        是否活跃用户
        :param current_user: 当前用户
        :return:
        """
        return current_user.is_active

    def is_superuser(self, current_user: User) -> bool:
        """
        是否超级用户
        :param current_user: 当前用户
        :return:
        """
        return current_user.is_superuser


user = CRUDUser(User)

if __name__ == '__main__':
    from app.api.utils.db import get_db

    # print(user.get_by_email(next(get_db()), email='123@163.com'))
    print(user.get(next(get_db()), 123))
